home *** CD-ROM | disk | FTP | other *** search
/ Introduction to 3D Game …ogramming with DirectX 12 / Introduction-to-3D-Game-Programming-with-DirectX-12.ISO / Code.Textures / Chapter 12 The Geometry Shader / TreeBillboards / Waves.cpp < prev    next >
C/C++ Source or Header  |  2016-03-02  |  5KB  |  173 lines

  1. //***************************************************************************************
  2. // Waves.cpp by Frank Luna (C) 2011 All Rights Reserved.
  3. //***************************************************************************************
  4.  
  5. #include "Waves.h"
  6. #include <ppl.h>
  7. #include <algorithm>
  8. #include <vector>
  9. #include <cassert>
  10.  
  11. using namespace DirectX;
  12.  
  13. Waves::Waves(int m, int n, float dx, float dt, float speed, float damping)
  14. {
  15.     mNumRows = m;
  16.     mNumCols = n;
  17.  
  18.     mVertexCount = m*n;
  19.     mTriangleCount = (m - 1)*(n - 1) * 2;
  20.  
  21.     mTimeStep = dt;
  22.     mSpatialStep = dx;
  23.  
  24.     float d = damping*dt + 2.0f;
  25.     float e = (speed*speed)*(dt*dt) / (dx*dx);
  26.     mK1 = (damping*dt - 2.0f) / d;
  27.     mK2 = (4.0f - 8.0f*e) / d;
  28.     mK3 = (2.0f*e) / d;
  29.  
  30.     mPrevSolution.resize(m*n);
  31.     mCurrSolution.resize(m*n);
  32.     mNormals.resize(m*n);
  33.     mTangentX.resize(m*n);
  34.  
  35.     // Generate grid vertices in system memory.
  36.  
  37.     float halfWidth = (n - 1)*dx*0.5f;
  38.     float halfDepth = (m - 1)*dx*0.5f;
  39.     for(int i = 0; i < m; ++i)
  40.     {
  41.         float z = halfDepth - i*dx;
  42.         for(int j = 0; j < n; ++j)
  43.         {
  44.             float x = -halfWidth + j*dx;
  45.  
  46.             mPrevSolution[i*n + j] = XMFLOAT3(x, 0.0f, z);
  47.             mCurrSolution[i*n + j] = XMFLOAT3(x, 0.0f, z);
  48.             mNormals[i*n + j] = XMFLOAT3(0.0f, 1.0f, 0.0f);
  49.             mTangentX[i*n + j] = XMFLOAT3(1.0f, 0.0f, 0.0f);
  50.         }
  51.     }
  52. }
  53.  
  54. Waves::~Waves()
  55. {
  56. }
  57.  
  58. int Waves::RowCount()const
  59. {
  60.     return mNumRows;
  61. }
  62.  
  63. int Waves::ColumnCount()const
  64. {
  65.     return mNumCols;
  66. }
  67.  
  68. int Waves::VertexCount()const
  69. {
  70.     return mVertexCount;
  71. }
  72.  
  73. int Waves::TriangleCount()const
  74. {
  75.     return mTriangleCount;
  76. }
  77.  
  78. float Waves::Width()const
  79. {
  80.     return mNumCols*mSpatialStep;
  81. }
  82.  
  83. float Waves::Depth()const
  84. {
  85.     return mNumRows*mSpatialStep;
  86. }
  87.  
  88. void Waves::Update(float dt)
  89. {
  90.     static float t = 0;
  91.  
  92.     // Accumulate time.
  93.     t += dt;
  94.  
  95.     // Only update the simulation at the specified time step.
  96.     if( t >= mTimeStep )
  97.     {
  98.         // Only update interior points; we use zero boundary conditions.
  99.         concurrency::parallel_for(1, mNumRows - 1, [this](int i)
  100.         //for(int i = 1; i < mNumRows-1; ++i)
  101.         {
  102.             for(int j = 1; j < mNumCols-1; ++j)
  103.             {
  104.                 // After this update we will be discarding the old previous
  105.                 // buffer, so overwrite that buffer with the new update.
  106.                 // Note how we can do this inplace (read/write to same element) 
  107.                 // because we won't need prev_ij again and the assignment happens last.
  108.  
  109.                 // Note j indexes x and i indexes z: h(x_j, z_i, t_k)
  110.                 // Moreover, our +z axis goes "down"; this is just to 
  111.                 // keep consistent with our row indices going down.
  112.  
  113.                 mPrevSolution[i*mNumCols+j].y = 
  114.                     mK1*mPrevSolution[i*mNumCols+j].y +
  115.                     mK2*mCurrSolution[i*mNumCols+j].y +
  116.                     mK3*(mCurrSolution[(i+1)*mNumCols+j].y + 
  117.                          mCurrSolution[(i-1)*mNumCols+j].y + 
  118.                          mCurrSolution[i*mNumCols+j+1].y + 
  119.                          mCurrSolution[i*mNumCols+j-1].y);
  120.             }
  121.         });
  122.  
  123.         // We just overwrote the previous buffer with the new data, so
  124.         // this data needs to become the current solution and the old
  125.         // current solution becomes the new previous solution.
  126.         std::swap(mPrevSolution, mCurrSolution);
  127.  
  128.         t = 0.0f; // reset time
  129.  
  130.         //
  131.         // Compute normals using finite difference scheme.
  132.         //
  133.         concurrency::parallel_for(1, mNumRows - 1, [this](int i)
  134.         //for(int i = 1; i < mNumRows - 1; ++i)
  135.         {
  136.             for(int j = 1; j < mNumCols-1; ++j)
  137.             {
  138.                 float l = mCurrSolution[i*mNumCols+j-1].y;
  139.                 float r = mCurrSolution[i*mNumCols+j+1].y;
  140.                 float t = mCurrSolution[(i-1)*mNumCols+j].y;
  141.                 float b = mCurrSolution[(i+1)*mNumCols+j].y;
  142.                 mNormals[i*mNumCols+j].x = -r+l;
  143.                 mNormals[i*mNumCols+j].y = 2.0f*mSpatialStep;
  144.                 mNormals[i*mNumCols+j].z = b-t;
  145.  
  146.                 XMVECTOR n = XMVector3Normalize(XMLoadFloat3(&mNormals[i*mNumCols+j]));
  147.                 XMStoreFloat3(&mNormals[i*mNumCols+j], n);
  148.  
  149.                 mTangentX[i*mNumCols+j] = XMFLOAT3(2.0f*mSpatialStep, r-l, 0.0f);
  150.                 XMVECTOR T = XMVector3Normalize(XMLoadFloat3(&mTangentX[i*mNumCols+j]));
  151.                 XMStoreFloat3(&mTangentX[i*mNumCols+j], T);
  152.             }
  153.         });
  154.     }
  155. }
  156.  
  157. void Waves::Disturb(int i, int j, float magnitude)
  158. {
  159.     // Don't disturb boundaries.
  160.     assert(i > 1 && i < mNumRows-2);
  161.     assert(j > 1 && j < mNumCols-2);
  162.  
  163.     float halfMag = 0.5f*magnitude;
  164.  
  165.     // Disturb the ijth vertex height and its neighbors.
  166.     mCurrSolution[i*mNumCols+j].y     += magnitude;
  167.     mCurrSolution[i*mNumCols+j+1].y   += halfMag;
  168.     mCurrSolution[i*mNumCols+j-1].y   += halfMag;
  169.     mCurrSolution[(i+1)*mNumCols+j].y += halfMag;
  170.     mCurrSolution[(i-1)*mNumCols+j].y += halfMag;
  171. }
  172.     
  173.